package org.dxy.trigger.http.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dxy.api.dto.request.unit.CreateUnitManageRequest;
import org.dxy.api.dto.request.unit.UpdateUnitManageRequest;
import org.dxy.api.dto.response.R;
import org.dxy.infrastructure.persistent.po.UnitManagePo;
import org.dxy.infrastructure.persistent.service.UnitManageService;
import org.dxy.trigger.http.service.UnitManageApplicationService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * @description: 单位管理应用服务实现类
 * @author: dxy
 * @createTime: 2025/1/21
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UnitManageApplicationServiceImpl implements UnitManageApplicationService {

    private final UnitManageService unitManageService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Long> create(CreateUnitManageRequest request) {
        try {
            // 验证单位编码是否已存在
            if (unitManageService.existsByUnitCode(request.getUnitCode(), null)) {
                return R.fail("单位编码已存在: " + request.getUnitCode());
            }

            // 验证基本单位是否存在
            if (request.getBaseUnitId() != null) {
                UnitManagePo baseUnit = unitManageService.getById(request.getBaseUnitId());
                if (baseUnit == null) {
                    return R.fail("基本单位不存在");
                }
            }

            // 构建实体
            UnitManagePo entity = UnitManagePo.builder()
                    .unitCode(request.getUnitCode())
                    .unitName(request.getUnitName())
                    .unitSymbol(request.getUnitSymbol())
                    .unitType(request.getUnitType())
                    .isBaseUnit(request.getIsBaseUnit())
                    .conversionFactor(request.getConversionFactor() != null ? request.getConversionFactor() : BigDecimal.ONE)
                    .baseUnitId(request.getBaseUnitId())
                    .description(request.getDescription())
                    .status(request.getStatus())
                    .build();

            // 保存
            boolean success = unitManageService.save(entity);
            if (success) {
                log.info("单位创建成功 - 单位编码: {}, ID: {}", request.getUnitCode(), entity.getId());
                return R.ok(entity.getId(), "单位创建成功");
            } else {
                log.error("单位创建失败 - 单位编码: {}", request.getUnitCode());
                return R.fail("单位创建失败");
            }
        } catch (Exception e) {
            log.error("单位创建异常 - 单位编码: {}", request.getUnitCode(), e);
            return R.fail("单位创建失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Void> update(UpdateUnitManageRequest request) {
        try {
            // 验证单位是否存在
            UnitManagePo existingEntity = unitManageService.getById(request.getId());
            if (existingEntity == null) {
                return R.fail("单位不存在");
            }

            // 验证单位编码是否已被其他单位使用
            if (unitManageService.existsByUnitCode(request.getUnitCode(), request.getId())) {
                return R.fail("单位编码已存在: " + request.getUnitCode());
            }

            // 验证基本单位是否存在
            if (request.getBaseUnitId() != null) {
                UnitManagePo baseUnit = unitManageService.getById(request.getBaseUnitId());
                if (baseUnit == null) {
                    return R.fail("基本单位不存在");
                }
                
                // 防止循环引用
                if (request.getBaseUnitId().equals(request.getId())) {
                    return R.fail("不能将自己设置为基本单位");
                }
            }

            // 更新实体
            UnitManagePo entity = new UnitManagePo();
            BeanUtils.copyProperties(request, entity);
            if (entity.getConversionFactor() == null) {
                entity.setConversionFactor(BigDecimal.ONE);
            }

            // 保存
            boolean success = unitManageService.updateById(entity);
            if (success) {
                log.info("单位更新成功 - ID: {}, 单位编码: {}", request.getId(), request.getUnitCode());
                return R.ok("单位更新成功");
            } else {
                log.error("单位更新失败 - ID: {}", request.getId());
                return R.fail("单位更新失败");
            }
        } catch (Exception e) {
            log.error("单位更新异常 - ID: {}", request.getId(), e);
            return R.fail("单位更新失败: " + e.getMessage());
        }
    }

    @Override
    public R<Page<UnitManagePo>> list(Page<UnitManagePo> page, UnitManagePo query) {
        try {
            Page<UnitManagePo> result = unitManageService.pageQuery(page, query);
            return R.ok(result, "查询成功");
        } catch (Exception e) {
            log.error("单位列表查询异常", e);
            return R.fail("单位列表查询失败: " + e.getMessage());
        }
    }

    @Override
    public R<UnitManagePo> getById(Long id) {
        try {
            UnitManagePo entity = unitManageService.getById(id);
            if (entity != null) {
                return R.ok(entity, "查询成功");
            } else {
                return R.fail("单位不存在");
            }
        } catch (Exception e) {
            log.error("单位详情查询异常 - ID: {}", id, e);
            return R.fail("单位详情查询失败: " + e.getMessage());
        }
    }

    @Override
    public R<UnitManagePo> getByUnitCode(String unitCode) {
        try {
            UnitManagePo entity = unitManageService.getByUnitCode(unitCode);
            if (entity != null) {
                return R.ok(entity, "查询成功");
            } else {
                return R.fail("单位不存在");
            }
        } catch (Exception e) {
            log.error("单位查询异常 - 单位编码: {}", unitCode, e);
            return R.fail("单位查询失败: " + e.getMessage());
        }
    }

    @Override
    public R<List<UnitManagePo>> getAllEnabled() {
        try {
            List<UnitManagePo> list = unitManageService.listAllEnabled();
            return R.ok(list, "查询成功");
        } catch (Exception e) {
            log.error("获取所有启用单位异常", e);
            return R.fail("获取所有启用单位失败: " + e.getMessage());
        }
    }

    @Override
    public R<List<UnitManagePo>> getByUnitType(String unitType) {
        try {
            List<UnitManagePo> list = unitManageService.listByUnitType(unitType);
            return R.ok(list, "查询成功");
        } catch (Exception e) {
            log.error("根据单位类型查询异常 - 单位类型: {}", unitType, e);
            return R.fail("根据单位类型查询失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Void> delete(Long id) {
        try {
            // 验证单位是否存在
            UnitManagePo entity = unitManageService.getById(id);
            if (entity == null) {
                return R.fail("单位不存在");
            }

            // 检查是否有其他单位依赖此单位作为基本单位
            List<UnitManagePo> dependentUnits = unitManageService.listByBaseUnitId(id);
            if (!dependentUnits.isEmpty()) {
                return R.fail("该单位被其他单位作为基本单位引用，不能删除");
            }

            // 删除
            boolean success = unitManageService.removeById(id);
            if (success) {
                log.info("单位删除成功 - ID: {}, 单位编码: {}", id, entity.getUnitCode());
                return R.ok("单位删除成功");
            } else {
                log.error("单位删除失败 - ID: {}", id);
                return R.fail("单位删除失败");
            }
        } catch (Exception e) {
            log.error("单位删除异常 - ID: {}", id, e);
            return R.fail("单位删除失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Void> batchDelete(List<Long> ids) {
        try {
            if (ids == null || ids.isEmpty()) {
                return R.fail("删除列表不能为空");
            }

            // 批量删除
            boolean success = unitManageService.batchDelete(ids);
            if (success) {
                log.info("批量删除单位成功 - 删除数量: {}", ids.size());
                return R.ok("批量删除成功");
            } else {
                log.error("批量删除单位失败 - ID列表: {}", ids);
                return R.fail("批量删除失败，可能存在被引用的单位");
            }
        } catch (Exception e) {
            log.error("批量删除单位异常 - ID列表: {}", ids, e);
            return R.fail("批量删除失败: " + e.getMessage());
        }
    }

    @Override
    public R<List<UnitManagePo>> getBaseUnits() {
        try {
            List<UnitManagePo> list = unitManageService.listBaseUnits();
            return R.ok(list, "查询成功");
        } catch (Exception e) {
            log.error("获取基础单位异常", e);
            return R.fail("获取基础单位失败: " + e.getMessage());
        }
    }

    @Override
    public R<List<UnitManagePo>> getBaseUnitsByType(String unitType) {
        try {
            List<UnitManagePo> list = unitManageService.listBaseUnitsByType(unitType);
            return R.ok(list, "查询成功");
        } catch (Exception e) {
            log.error("根据类型获取基础单位异常 - 单位类型: {}", unitType, e);
            return R.fail("根据类型获取基础单位失败: " + e.getMessage());
        }
    }
}